home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part1 / 7793 < prev    next >
Encoding:
Text File  |  1996-08-05  |  5.2 KB  |  160 lines

  1. Path: lr46pstn.lr.tudelft.nl!koen
  2. From: koen@lr46pstn.lr.tudelft.nl (Koen D'Hondt)
  3. Newsgroups: comp.lang.c
  4. Subject: Using regexec for multiple patterns. How???
  5. Date: 28 Feb 1996 23:44:51 GMT
  6. Organization: Ripley Software Development
  7. Sender: koen@dutlhs1.lr.tudelft.nl
  8. Distribution: all
  9. Message-ID: <4h2pdj$fui@mo6.rc.tudelft.nl>
  10. NNTP-Posting-Host: lr46pstn.lr.tudelft.nl
  11.  
  12. Hi All,
  13.  
  14. I've been experimenting with regcomp and friends to do pattern-matching in
  15. texts, but I've run into a few problems trying to search for multiple 
  16. occurances of a search pattern. The regcomp and regexec are the GNU stuff. 
  17. The system I'm using is Linux 1.3.63.
  18.  
  19. The first problem is that regcomp doesn't seem to support the [:XXXXX:] 
  20. character classes. I tried something like regcomp(regex, "[:digit:]+", 0)
  21. but using the compiled pattern matches any words containing the characters
  22. :digit, so digits aren't matched... Using [0-9]+ works.
  23.  
  24. I've been looking at the regex.c, and the support for character classes 
  25. should be there, regardless of what flags are fed to regcomp.
  26.  
  27. The second problem is trying to search for multiple occurances of a pattern
  28. in a string. As I understand from the man-page and regex.info, using regexec 
  29. in the following way: regexec(regex, text, 10, pmatch, 0) would give me up  
  30. to 10 matches, with the positions returned in pmatch[]. pmatch elements not
  31. used have the rm_so field set to -1 (which is not the case, unused elems are
  32. set to a silly value like 10^9 or so). 
  33.  
  34. Here's the thing I wrote to get acquinted with regcomp, regexec:
  35. /*****
  36. * test_regex.c : regular expression search.
  37. *****/ 
  38.  
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <string.h>
  42. #include <regex.h>
  43.  
  44. static char *text = {"
  45. Pippin looked behind. The number of Ents had grown --or what was happening?. 
  46. Where the dim bare slopes that they had crossed lie, he thought he saw groves 
  47. of trees. But they were moving! Could it be that the trees of Fangorn were 
  48. awake, and the forest was rising, marching over the hills to war? He rubbed 
  49. his eyes wondering if sleep and shadow had deceived him; but the great grey 
  50. shapes moved steadily onward. There was a noise like wind in many branches. 
  51. The Ents were drawing near the crest of the ridge now, and all song had 
  52. ceased. Night fell, and there was silence: nothing was to be heard save a 
  53. faint quiver of the earth beneath the feet of the Ents, and a rustle, the 
  54. shade of a whisper as of many drifting leaves. At last they stood upon 
  55. the summit, and looked down into a dark pit: the great cleft at the end of 
  56. the mountains: Nan Curunir, the Valley of Saruman.
  57. 'Night lies over Isengard', said Treebeard.
  58. Quote from The Lord of the Rings, page 508."};
  59.  
  60. /****
  61. * compile a regular expression, returning the compiled pattern on success
  62. * or NULL on failure
  63. *****/
  64. regex_t
  65. *compile_re(char *re_string)
  66. {
  67.     int reg_err;
  68.     char buf[128];
  69.     regex_t *regex = NULL;
  70.  
  71.     regex = (regex_t*)malloc(sizeof(regex_t));
  72.  
  73.     if((reg_err = regcomp(regex, re_string, REG_EXTENDED))!=0)
  74.     {
  75.         regerror(reg_err, regex, buf, 128); 
  76.         fprintf(stderr,"compile_re failed: %s\n", buf); 
  77.         free(regex);
  78.         return(NULL);
  79.     }
  80.     return(regex);
  81. }
  82.  
  83. /****
  84. * go do a regex search on the given string with the given pattern
  85. * Count indicates how many times we should search.
  86. ****/
  87. int
  88. search_re(regex_t *regex, char *search_text, int count)
  89. {
  90.     regmatch_t *pmatch;
  91.     char *chPtr, buf[128];
  92.     int i, result;
  93.  
  94.     pmatch = (regmatch_t*)malloc(count * sizeof(regmatch_t));
  95.  
  96.     result = regexec(regex, search_text, count, pmatch, 0);
  97.     if(result == REG_NOMATCH)
  98.     {
  99.         printf("No match found\n");
  100.         free(pmatch);
  101.         return(-1);
  102.     }
  103. /* this causes a SIGSEGV when count > 1 */
  104.     for(i = 0; i < count && pmatch[i].rm_so != -1; i++)
  105.     {
  106.         bzero(buf,128); 
  107.         chPtr = &search_text[pmatch[i].rm_so];
  108.         strncpy(buf, chPtr, pmatch[i].rm_eo - pmatch[i].rm_so);
  109.         strcat(buf,"\0");
  110.         printf("%i: start at %i, end at %i (%s)\n",
  111.             i, pmatch[i].rm_so, pmatch[i].rm_eo, buf);  
  112.     }
  113.     printf("No of matches found: %i\n",i);
  114.     free(pmatch);
  115.     return(0);
  116. }
  117.  
  118. int main(int argc, char **argv)
  119. {
  120.     regex_t *preg;
  121.  
  122.     printf("regex testing, text to search:\n");
  123.     printf("%s\n", text);
  124.  
  125. /* simple search, 1 occurance */
  126.     printf("Searching for Saruman\n");
  127.     if((preg = compile_re("Saruman"))!= NULL)
  128.     {
  129.         search_re(preg, text, 1);
  130.         regfree(preg);
  131.         free(preg);
  132.     }
  133. /* simple search, should find 3 occurances */
  134.     printf("Searching for Ents\n");
  135.     if((preg = compile_re("Ents")) != NULL)
  136.     {
  137.         search_re(preg, text, 10);
  138.         regfree(preg);
  139.         free(preg);
  140.     }
  141.     return(0);
  142. }
  143.  
  144. FYI: I've tried it using the regcomp, regexec supplied in libc, and tried
  145. using a compiled version of regex.c, both give the same (non)result.
  146.  
  147. I now have a version which calls regexec every time for the number of matches 
  148. I want, supplying an updated search text every time a match has been found, 
  149. but to my opinion it could be done a lot easier if regexec could do it all 
  150. at once. 
  151.  
  152. Greets,
  153. Koen D'Hondt.
  154.  
  155. -- 
  156. Koen D'Hondt                                                   Niels Hilbrink
  157. koen@dutlhs1.lr.tudelft.nl                        niels@dutlcc3.lr.tudelft.nl
  158.  
  159. Ripley Software Development  finger niels@dutlcc3.lr.tudelft.nl for more info.
  160.